const get = require('get-value');
const obj = { a: { b: { c: { d: 'foo' } } } };

/*
console.log(get(obj));            //=> { a: { b: { c: { d: 'foo' } } } };
console.log(get(obj, 'a'));       //=> { b: { c: { d: 'foo' } } }
console.log(get(obj, 'a.b'));     //=> { c: { d: 'foo' } }
console.log(get(obj, 'a.b.c'));   //=> { d: 'foo' }
console.log(get(obj, 'a.b.c.d')); //=> 'foo'

console.log(get(obj, 3));
console.log(get(obj, true));
console.log(get(obj, 'a.b.c.e'));
*/



console.log(get(obj, 'a.b'));
console.log('-----------------------\n')

console.log(getValue(obj, 'a.b.c.d'));
console.log(getValue(obj, 'a'));

console.log('----------------- getValueV2 ------------------\n')
console.log(getValueV2(obj, 'a.b.c.d'.split('.')));
console.log(getValueV2(obj, 'a'));


function getValue(arr, property) {
	return getValueV1.apply(null, arguments)
}


function getValueV2(target, path, options) {

	if(!isPlainObject(options)) {
		options = {default: options}
	}


	if(typeof path ==='number') {
		path = String(path)
	}

	// 数组形式的路径
	const isArray = Array.isArray(path)
	const isString = typeof path === 'string'

	// 层级属性分隔符, 默认使用 '.'进行分隔
	const splitChar = options.separator || '.'
	const joinChar = options.joinChar || (typeof splitChar === 'string' ? splitChar : '.')

	if(!isString && !isArray) {
		return target
	}


	let segs = isArray ? path : path.split(splitChar)

	let len = segs.length
	for (var idx = 0; idx < len; idx++) {
		let prop = segs[idx]

		if (typeof prop === 'number') {
	      prop = String(prop);
	    }

	    if (prop in target) {
	      	target = target[prop]
	    } else {
	    	break
	    }
	}

	if(idx === len) {
		return target
	}

	return options.default
}


/**
 * 是否为纯对象
 * @param  {[type]}  obj [description]
 * @return {Boolean}     [description]
 */
function isPlainObject(obj) {
	if (typeof obj !== 'object' || obj === null) return false

	proto = Object.getPrototypeOf(obj);
    if (!proto) {
        return true;
    }

    return obj.constructor === Object
}





/**
 * 字符串形式的多级键名
 * @param  {[type]} obj  [description]
 * @param  {[type]} prop [description]
 * @return {[type]}      [description]
 */
function getValueV1(obj, prop) {

	var props = prop.split('.')
	var key, value;
	var tmpObj = obj
	for (var i = 0; i < props.length; i++) {
		key = props[i]
		value = tmpObj[key]
		if(value === undefined) {
			break
		}
		tmpObj = value
	}
	return value
}
